{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 计算过程:输入一个字母，预测下一个字母\n",
    "\n",
    "    独热码编码abcde\n",
    "    10000 a \n",
    "    01000 b \n",
    "    00100 c \n",
    "    00010 d \n",
    "    00001 e\n",
    "    \n",
    "    随机生成Why、Whh、Wxh三个参数矩阵\n",
    "    \n",
    "     \n",
    "    Why                    yt[0.0,0.1,0.4,-0.7,0.1]  //yt[0.0,0.1,0.4,-0.7,0.1]→yt[0.02  0.02  0.91 0.03  0.02 ]=c     \n",
    "    [[-1.7  0.7  -1.7  1.7  0.7]        ⬆\n",
    "     [-1.6  -1.6  0.7  1.3  1.4]        ⬆by[0.0  0.1  0.4  -0.7  0.1]\n",
    "     [-1.4  1.9  1.2  1.7  -1.9 ]]       \n",
    "                              ⬆\n",
    "                              ⬆\n",
    "    Whh                         \n",
    "    [[-0.9 -0.2  -0.4]          ht[0.0  0.0  0.0]     //ht[0.0  0.0  0.0]→ht[-0.9  0.8  0.7]\n",
    "     [-0.3  0.9   0.2]              \n",
    "     [ 0.4  0.3  -0.9]]              ⬆\n",
    "                              ⬆bh[0.5  0.3  -0.2]\n",
    "    \n",
    "                              ⬆\n",
    "    Wxh                     xt[0,1,0,0,0]      //b\n",
    "    [[ 0.5-1.7  1.7 ]               \n",
    "     [-2.3 0.8  1.1 ]\n",
    "     [ 1.3 1.7  1.4 ]\n",
    "     [ 0.3 0.8 -1.1 ]\n",
    "     [-1.8 -2.0-1.0 ]]\n",
    "\n",
    "    ht = tanh( Xt * Wxh + ht~ * Whh + bh )\n",
    "      = tanh([-2.3   0.8  1.1 ] + 0 + [ 0.5  0.3  -0.2]）\n",
    "      = tanh[-1.8  1.1  0.9 ]\n",
    "      = [-0.9  0.8  0.7]\n",
    "\n",
    "    yt = softmax( ht * Why + by )\n",
    "      = softmax([-0.7  -0.6  2.9  0.7  -0.8] + [ 0.0  0.1  0.4  -0.7  0.1]) \n",
    "      = softmax([-0.7  -0.5  3.3  0.0  -0.7]) \n",
    "      = [0.02  0.02  0.91 0.03  0.02 ]\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-------------load the model-----------------\n",
      "Train on 5 samples\n",
      "Epoch 1/100\n",
      "5/5 [==============================] - 2s 363ms/sample - loss: 0.0835 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 2/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0826 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 3/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0818 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 4/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0810 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 5/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0802 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 6/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.0795 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 7/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0787 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 8/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.0780 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 9/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0772 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 10/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0765 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 11/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0758 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 12/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0751 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 13/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0744 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 14/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.0738 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 15/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0731 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 16/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.0725 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 17/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.0718 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 18/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0712 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 19/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0706 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 20/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0699 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 21/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0693 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 22/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0688 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 23/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.0682 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 24/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.0676 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 25/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0670 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 26/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0665 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 27/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0659 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 28/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0654 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 29/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0648 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 30/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0643 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 31/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0638 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 32/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0633 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 33/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0628 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 34/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0623 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 35/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0618 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 36/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0613 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 37/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0608 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 38/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.0604 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 39/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0599 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 40/100\n",
      "5/5 [==============================] - 0s 20ms/sample - loss: 0.0594 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 41/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0590 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 42/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0585 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 43/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0581 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 44/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0577 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 45/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0572 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 46/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0568 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 47/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.0564 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 48/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0560 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 49/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0556 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 50/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0552 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 51/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0548 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 52/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0544 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 53/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0540 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 54/100\n",
      "5/5 [==============================] - 0s 28ms/sample - loss: 0.0536 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 55/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0532 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 56/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0528 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 57/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0525 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 58/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0521 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 59/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0517 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 60/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0514 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 61/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0510 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 62/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0507 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 63/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0503 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 64/100\n",
      "5/5 [==============================] - 0s 20ms/sample - loss: 0.0500 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 65/100\n",
      "5/5 [==============================] - 0s 25ms/sample - loss: 0.0497 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 66/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0493 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 67/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.0490 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 68/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0487 - sparse_categorical_accuracy: 1.0000\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 69/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0484 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 70/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0481 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 71/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0477 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 72/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0474 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 73/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0471 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 74/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0468 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 75/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0465 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 76/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0462 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 77/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0459 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 78/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0456 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 79/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0454 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 80/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0451 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 81/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0448 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 82/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0445 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 83/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.0442 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 84/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.0440 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 85/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0437 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 86/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0434 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 87/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0432 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 88/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.0429 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 89/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0426 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 90/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0424 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 91/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0421 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 92/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0419 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 93/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0416 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 94/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0414 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 95/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0411 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 96/100\n",
      "5/5 [==============================] - 0s 24ms/sample - loss: 0.0409 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 97/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.0407 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 98/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.0404 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 99/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.0402 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 100/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.0400 - sparse_categorical_accuracy: 1.0000\n",
      "Model: \"sequential_2\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "simple_rnn_2 (SimpleRNN)     multiple                  27        \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              multiple                  20        \n",
      "=================================================================\n",
      "Total params: 47\n",
      "Trainable params: 47\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEICAYAAABYoZ8gAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3deXwU9fnA8c+TA8IdCOFKkIAgNwkQuatQbIugYsWLQwVP8D7aetVqa1u17U8rrQUBwaIURSyKFo+iHIpcAQEJlxxBAggBhADhSMjz+2MHusZNsoHNzh7P+/XaV3ZnvrPzzOzMk+985/iKqmKMMSZ6xLgdgDHGmOCyxG+MMVHGEr8xxkQZS/zGGBNlLPEbY0yUscRvjDFRxhL/WRKRD0TkpkCXNSZc2T4RPiSaruMXkSNeH6sDJ4BTzuc7VHVa8KM6dyLSHNgCjFfVO92Ox4SPSNsnRKQv8LqqprodSyiLqhq/qtY8/QK+AS73GnZmAxeROPeiPCs3At8B14tI1WDOWERigzk/E1gRvE+YMkRV4i+NiPQVkVwReVhEvgWmiEhdEXlfRPJE5DvnfarXNPNF5Fbn/UgR+VxE/uKU3SYil55l2eYislBEDovIXBF5SUReL2cRbgR+DRQCl5dYtsEiskpE8kVki4gMcIbXE5EpIrLLieMd7/hKfIeKSEvn/asiMk5E5ojIUaCfiAwSkS+deewQkadKTN9HRL4QkYPO+JEicqGI7PFOKCIyRERWlbOsJggiYJ/wtUxtnfkeFJFsEbnCa9xAEVnnzGOniPzCGV7fWc6DInJARD4TkbDPm2G/AAHUCKgHNANux7NupjifzwOOAX8vY/ruwEagPvAn4BURkbMo+y9gGZAEPAXcUFbQIvIjIBV4A5iB55/A6XHdgKnAL4FE4CIgxxn9Gp5D+/ZAA+CFsuZTwjDgD0At4HPgqDPfRGAQMEZErnRiOA/4APgbkAxkAKtUdTmwH/iJ1/eOcOIyoSEs9wlfRCQeeA/4GM/2fg8wTURaO0VewdO0VQvoAHzqDH8IyMWz7TYEHgPCv31cVaPyhScBXuK87wucBBLKKJ8BfOf1eT5wq/N+JLDZa1x1PBtHo4qUxbMzFQHVvca/jqfNsrS4JgHvOO974qn1N3A+vwy84GOaxkAxUNfHuJHA5yWGKdDSef8qMLWcdfvX0/MFHgVmlVLuYWCa874eUAA0dnvbiNZXJOwTTty5Pob/CPgWiPEaNh14ynn/DXAHULvEdL8D3j29/UfKy2r8/5OnqsdPfxCR6iLysohsF5F8YCGQKKW3aX97+o2qFjhva1awbBPggNcwgB2lBSwi1YBrgGnOdy3GswEPc4o0xXPSt6Smzny+K+27y/G9mESku4jMc5oADgGj8dTcyooBPDvw5SJSE7gW+ExVd59lTCbwwm6fKEMTYIeqFnsN2w6kOO+HAAOB7SKyQER6OsP/DGwGPhaRrSLyyFnMO+RY4v+fkodvDwGtge6qWhtPMwlAaYeqgbAbqCci1b2GNS2j/M+B2sA/RORbpy02hf819+wAzvcx3Q5nPok+xh3FU+MCQEQa+ShTcl39C5gNNFXVOsB4/reeSosBVd0JLHaW4wasmSfUhOM+UZpdQNMS7fPnATsBVHW5qg7G0wz0Dp5mU1T1sKo+pKot8Jw/e1BE+p/F/EOKJf7S1cLThnlQROoBT1b2DFV1O5AFPCUiVZxax+VlTHITMBnoiOewOwPoDWSISEc87ZajRKS/iMSISIqItHFq1R/g+YdRV0TiReT0TrwaaC8iGSKSgKdNtTy18NTKjjvnFYZ5jZsGXCIi14pInIgkiUiG1/ipwK+cZZjlx7yMe8JhnwBARBK8X3jOERwFfuVs732d73nD+d7hIlJHVQuBfJxLWkXkMhFp6ZxvOD38lM+ZhhFL/KX7K1AN2AcsAT4M0nyH42mr3w/8HngTz7XV3yMiKUB/4K+q+q3Xa4UT602qugwYhefE7SFgAZ4Tc+CpYRcCG4C9wP0AqroJT7vmXOBrPCdvy3Mn8DsROQz8Bqe25HzfN3gOoR8CDgCrgHSvaWc5Mc1S1aN+zMu4J6T3CS8peP5Beb+aAlcAl+KJ/x/Ajaq6wZnmBiDHacIajedCA4BWePaFI3iOTv+hqvMDtWBuiaobuMKRiLwJbFDVSq9duUVEtuC5omKu27GY0BcN+0Rlsxp/iBHP9e3nO00zA4DBeNocI5KIDMHTlvxpeWVNdIq2fSIY7G680NMI+Deea5ZzgTGq+qW7IVUOEZkPtANuKHG1hTHeomafCBZr6jHGmChjTT3GGBNlQrKpp379+pqWluZ2GCZCrVixYp+qJgd7vrZdm8pUke06JBN/WloaWVlZbodhIpSIbHdjvrZdm8pUke3amnqMMSbKWOI3xpgoY4nfGGOiTEi28VeWwsJCcnNzOX78ePmFTdhLSEggNTWV+Ph4t0MJe7bvhI5AbNdRlfhzc3OpVasWaWlplN4fhIkEqsr+/fvJzc2lefPmbocT9mzfCQ2B2q6jqqnn+PHjJCUl2YYbBUSEpKQkq6EGiO07oSFQ23VUJX7ANtwoYr91YNn6DA2B+B2iLvEbE2rmrtvDpM+2uh2GiSKW+INo//79ZGRkkJGRQaNGjUhJSTnz+eTJk2VOm5WVxb333lvuPHr16hWocAG47777SElJobjYnqFWWT7ZsJf/+3gTR04UuR1KyAqnfWf+/PlcdtllAfmuyhJVJ3fdlpSUxKpVqwB46qmnqFmzJr/4xS/OjC8qKiIuzvdPkpmZSWZmZrnz+OKLLwITLFBcXMysWbNo2rQpCxcupG/fvgH7bm+nTp0iNra0blsj39VdU5i+7BvmfLWbazPPplfByBdu+06osxq/y0aOHMmDDz5Iv379ePjhh1m2bBm9evWic+fO9OrVi40bNwLfr0U89dRT3HzzzfTt25cWLVowduzYM99Xs2bNM+X79u3L1VdfTZs2bRg+fDinn8Q6Z84c2rRpQ58+fbj33ntLrZ3MmzePDh06MGbMGKZPn35m+J49e/j5z39Oeno66enpZ3aYqVOn0qlTJ9LT07nhhhvOLN/MmTN9xtevXz+GDRtGx44dAbjyyivp2rUr7du3Z8KECWem+fDDD+nSpQvp6en079+f4uJiWrVqRV5eHuD5B9WyZUv27dt3tj+Dq7qcV5fm9Wvw9opct0MJK6G87/gyffp0OnbsSIcOHXj44YcBT6Vn5MiRdOjQgY4dO/LCCy8AMHbsWNq1a0enTp24/vrrz31llRC1Nf7fvpfNul35Af3Odk1q8+Tl7Ss83aZNm5g7dy6xsbHk5+ezcOFC4uLimDt3Lo899hhvv/32D6bZsGED8+bN4/Dhw7Ru3ZoxY8b84LreL7/8kuzsbJo0aULv3r1ZtGgRmZmZ3HHHHSxcuJDmzZszdOjQUuOaPn06Q4cOZfDgwTz22GMUFhYSHx/Pvffey8UXX8ysWbM4deoUR44cITs7mz/84Q8sWrSI+vXrc+DAgXKXe9myZaxdu/bMZWmTJ0+mXr16HDt2jAsvvJAhQ4ZQXFzMbbfddibeAwcOEBMTw4gRI5g2bRr3338/c+fOJT09nfr161dwzYcGEWFIlxT+8vEmvtlfwHlJ1cufyEW275S/75S0a9cuHn74YVasWEHdunX56U9/yjvvvEPTpk3ZuXMna9euBeDgwYMAPPvss2zbto2qVaueGRZIVuMPAddcc82Zpo5Dhw5xzTXX0KFDBx544AGys7N9TjNo0CCqVq1K/fr1adCgAXv27PlBmW7dupGamkpMTAwZGRnk5OSwYcMGWrRocSbZlrbxnjx5kjlz5nDllVdSu3ZtunfvzscffwzAp59+ypgxYwCIjY2lTp06fPrpp1x99dVnkm+9evXKXe5u3bp971rksWPHkp6eTo8ePdixYwdff/01S5Ys4aKLLjpT7vT33nzzzUydOhXw/MMYNWpUufMLZT/vkooIzFxptf6KCMV9x5fly5fTt29fkpOTiYuLY/jw4SxcuJAWLVqwdetW7rnnHj788ENq164NQKdOnRg+fDivv/56qU1Y5yJqa/xnU7uoLDVq1Djz/oknnqBfv37MmjWLnJycUtvVq1ateuZ9bGwsRUU/PDHoq4y/He98+OGHHDp06EwzTEFBAdWrV2fQoEE+y6uqz8vM4uLizpwYVtXvnYjzXu758+czd+5cFi9eTPXq1enbty/Hjx8v9XubNm1Kw4YN+fTTT1m6dCnTpk3za7lCVUpiNXqfX5+3V+Ryf/9WxMSE7qWTtu9UXGnT1q1bl9WrV/PRRx/x0ksvMWPGDCZPnsx//vMfFi5cyOzZs3n66afJzs4O6D8Aq/GHmEOHDpGSkgLAq6++GvDvb9OmDVu3biUnJweAN99802e56dOnM2nSJHJycsjJyWHbtm18/PHHFBQU0L9/f8aNGwd42ijz8/Pp378/M2bMYP/+/QBnmnrS0tJYsWIFAO+++y6FhYU+53fo0CHq1q1L9erV2bBhA0uWLAGgZ8+eLFiwgG3btn3vewFuvfVWRowYwbXXXhsRJ4evyUxl58FjLNm63+1QwlKo7Du+dO/enQULFrBv3z5OnTrF9OnTufjii9m3bx/FxcUMGTKEp59+mpUrV1JcXMyOHTvo168ff/rTnzh48CBHjhwJ6LJY4g8xv/rVr3j00Ufp3bs3p06dCvj3V6tWjX/84x8MGDCAPn360LBhQ+rUqfO9MgUFBXz00Uffq93XqFGDPn368N577/Hiiy8yb948OnbsSNeuXcnOzqZ9+/Y8/vjjXHzxxaSnp/Pggw8CcNttt7FgwQK6devG0qVLv1dD8zZgwACKioro1KkTTzzxBD169AAgOTmZCRMmcNVVV5Gens511113ZporrriCI0eOhH0zz2k/a9+IWglxzMja4XYoYSkU9p3TPvnkE1JTU8+8cnJyeOaZZ+jXrx/p6el06dKFwYMHs3PnTvr27UtGRgYjR47kmWee4dSpU4wYMYKOHTvSuXNnHnjgARITEwO7MKoacq+uXbtqZVi3bl2lfG+4OXz4sKqqFhcX65gxY/T55593OaKzs3z5cu3Tp0+ZZXz95kCWhuh2/fisNXrB43P0YMHJcssGk+07HqGy75zrdm01/ig0ceJEMjIyaN++PYcOHeKOO+5wO6QKe/bZZxkyZAjPPPOM26EE1HWZ53GiqJjZq3e5HYrxIRL2HQDRczhhUVkyMzO1MrqoW79+PW3btg3495rQ5es3F5EVqlr+HT0B5s92raoMHPs58bHC7Lv7BCmy8tm+E1rOdbuOuhp/KP6jM5UjHH9rEeG6zFTW5B4K+LXy5yoc12ckCsTvEFWJPyEhgf3799sGHAXUeW55QkKC26FU2JWdU6gSF8Mby79xO5QzbN8JDYHarqPqOv7U1FRyc3PP3OpvItvpnopKIyIDgBeBWGCSqj5bYrw44wcCBcBIVV3pjHsAuBVQ4CtglKoG5OH/idWrMLBDI2Z9uZNHL21LtSruX6pq+07oKG+79kdUJf74+HjrjckAICKxwEvAT4BcYLmIzFbVdV7FLgVaOa/uwDigu4ikAPcC7VT1mIjMAK4HXg1UfNddeB7vrNrFnK92M6True3kgWD7TmSJqqYeY7x0Azar6lZVPQm8AQwuUWYwMNW5Wm4JkCgijZ1xcUA1EYkDqgMBvQynR4t6NK9fI6Sae0zksMRvolUK4H2nVK4zrNwyqroT+AvwDbAbOKSqH/uaiYjcLiJZIpJVkWYSEWFot6Ysz/mOTXsO+z2dMf4oN/GLyGQR2Ssia0sZLyIyVkQ2i8gaEelSYnysiHwpIu8HKmhjAsDXw3BKnrn0WUZE6uI5GmgONAFqiMgIXzNR1QmqmqmqmcnJyRUKcEiXVOJjhenLrNZvAsufGv+rwIAyxnu3g96Opx3U233A+rMJzphKlAt493qSyg+ba0orcwmwTVXzVLUQ+DcQ2K7PgKSaVflZ+0a8vSKX44WBfwSBiV7lJn5VXQiU9XD1UttBRSQVGARMCkSwxgTQcqCViDQXkSp4Ts7OLlFmNnCjc1TbA0+Tzm48TTw9RKS6c+VPfyqpcjO8ezPyjxfx/prdlfH1JkoFoo2/rLbSvwK/AsrtsPVs20KNORuqWgTcDXyEJ2nPUNVsERktIqOdYnOArcBmYCJwpzPtUmAmsBLPpZwxwAQqQY8W9WiRXINpS7dXxtebKBWIyzlLawe9DNirqitEpG95X6KqE3B2nszMTLtLxFQ6VZ2DJ7l7Dxvv9V6Bu0qZ9kngyUoNEM9J3uHdm/H0++vI3nWI9k18Pw3SmIoIRI2/tHbQ3sAVIpKD51K5H4vI6wGYnzFR5eouqSTEx/D6EjvJawIjEInfZzuoqj6qqqmqmoan/fRTVfV55YMxpnR1qsdzRXoT3vlyJ/nHfXdkY0xF+HM553RgMdBaRHJF5BZ/2kGNMYFzQ480jhWe4u0V1ievOXfltvGrapk9CpfVDupVZj4wvyKBGWP+p2NqHdKbJvLaku2M7JXmsx9iY/xld+4aEyZu6tmMrXlHWbTZ+uQ158YSvzFhYmDHxiTVqMLUxTluh2LCnCV+Y8JEQnws13drytz1e9hxoMDtcEwYs8RvTBgZ3r0ZIsLrdkOXOQeW+I0JI00Sq/Gz9g15c/kOjp205/eYs2OJ35gwc1PPNA4WFPLuqp1uh2LClCV+Y8JMt+b1aNu4NlMW5VgfuOasWOI3JsyICDf3TmPjnsN8scUu7TQVZ4nfmDB0eXoTkmpUYfLn29wOxYQhS/zGhKGE+FiG92jGJxv2sjXviNvhmDBjid+YMHVDj2ZUiY1hyqIct0MxYcYSvzFhKrlWVa7IaMLMFbkcLDjpdjgmjFjiNyaM3dKnOccKT/Ev65DdVIAlfmPCWNvGtenTsj7//CKHk0Xl9nBqDGCJ35iwd+uPmrMn/wTvrd7ldigmTFjiNybMXXxBMhc0rMnEz7baDV3GL5b4jQlzIsJtP2rBhm8Ps/DrfW6HY8KAJX5jIsDgjBQa1q7KhIVb3A7FhAFL/MZEgCpxMdzcuzmLNu/nq9xDbodjQpwlfmMixNDu51GrahzjrdZvymGJ35gIUTshnuE9mvHBV7vJ2XfU7XBMCLPEb0wEubl3GnExMUz4bKvboZgQZonfmAjSoHYCQ7qmMjMrl735x90Ox4QoS/zGRJjRF7egqLiYV+yRzaYUlviNiTDNkmowqFMTXl+ynUMFhW6HY0KQJX5jItCdfc/n6MlTvPpFjtuhmBBkid+YCNS2cW0uaduAKV9s4+iJIrfDMSHGEr8xEequfi05WFDI60u2ux2KCTGW+I2JUJ3Pq0uflvWZ+NlWjheecjscE0Is8RsTwe75cUv2HTnJdOuoxXgpN/GLyGQR2Ssia0sZLyIyVkQ2i8gaEeniDG8qIvNEZL2IZIvIfYEO3hhTtu4tkujevB7jF2yxWr85w58a/6vAgDLGXwq0cl63A+Oc4UXAQ6raFugB3CUi7c4+VGPM2bivfyv25J9gRtYOt0MxIaLcxK+qC4EDZRQZDExVjyVAoog0VtXdqrrS+Y7DwHogJRBBGxMIIjJARDY6R6uP+Bhf2tFsaxFZ5fXKF5H7g78E/ul5fhIXptXlH/O2cKLIav0mMG38KYB3VSKXEgleRNKAzsDSAMzPmHMmIrHAS3iOWNsBQ30ckfo8mlXVjaqaoaoZQFegAJgVrNgrSkS4r/8FfJt/nBnLrdZvApP4xcewM/2/iUhN4G3gflXNL/VLRG4XkSwRycrLywtAWMaUqRuwWVW3qupJ4A08R6/efB7NlijTH9iiqiF9zWTvlklkNqvLS/Osrd8EJvHnAk29PqcCuwBEJB5P0p+mqv8u60tUdYKqZqpqZnJycgDCMqZM5R6p+lnmemB6aTMJlQqNiPDATzy1/jet1h/1ApH4ZwM3Ou2hPYBDqrpbRAR4BVivqs8HYD7GBFKZR6r+lBGRKsAVwFulzSSUKjS9zk+iW/N6vDRvs9X6o5w/l3NOBxYDrUUkV0RuEZHRIjLaKTIH2ApsBiYCdzrDewM3AD/2Ogk2MPCLYMxZKfVItQJlLgVWquqeSokwwESEB39yAXsPn7C7eaNcXHkFVHVoOeMVuMvH8M/xXWMyJhQsB1qJSHNgJ54mm2ElyswG7haRN4DuOEezXuOHUkYzTyjq0SKJXucnMW7+FoZ2O48aVctNASYC2Z27JiqpahFwN/ARnkuNZ6hqtp9Hs4hIdeAnQJnnrkLRQz9tzf6jJ+3JnVHM/t2bqKWqc/Akd+9h473e+zyadcYVAEmVGmAl6dqsLj9u04CXF2xhRI9m1KkW73ZIJsisxm9MFHropxeQf7yIiQutb95oZInfmCjUvkkdLuvUmMmLtpF3+ITb4Zggs8RvTJR68CcXcKKomJfmbXY7FBNklviNiVItkmtybWYq05ZuZ8eBArfDMUFkid+YKHZf/wuIEeH5/25yOxQTRJb4jYlijeokMLJ3Gu+s2kn2rkNuh2OCxBK/MVHuzotbUjshnuc+3Oh2KCZILPEbE+XqVI/n7n4tWbgpj0Wb97kdjgkCS/zGGG7o2YyUxGr8cc56iotLPqvORBpL/MYYEuJj+eXPWpO9K5/Zq0s+q85EGkv8xhgArkhvQoeU2vz5o4322OYIZ4nfGANATIzw2MC27Dx4jMmLtrkdjqlElviNMWf0Or8+l7RtwD/mbWHfEXuUQ6SyxG+M+Z5HLm3L8cJTdlNXBLPEb4z5npYNajKiRzPeWPYNG7897HY4phJY4jfG/MD9l7SiVkI8T7+/Dk+3BCaSWOI3xvxAYvUq3H9JKz7fvI9P1u91OxwTYJb4jTE+jejRjJYNavL7/6zjRJFd3hlJLPEbY3yKj43hicvakbO/gCmLctwOxwSQJX5jTKkuviCZS9o24G+ffM3e/ONuh2MCxBK/MaZMvx7UjsJTyrMfbHA7FBMglviNMWVKq1+D2y5qzr+/3ElWzgG3wzEBYInfGFOuu/q1pHGdBH7zbjan7OmdYc8SvzGmXNWrxPHrQe1YtzufaUu3ux2OOUeW+I0xfhnYsRG9Wybx54822nN8wpwlfmOMX0SE317RgeOFp3hmjp3oDWeW+I0xfmvZoCa3/agFb6/MZenW/W6HY86SJX5jTIXc/eOWpCRW44l313KyqNjtcMxZsMRvjKmQ6lXi+O0V7dm05wivfG4dtoSjchO/iEwWkb0israU8SIiY0Vks4isEZEuXuMGiMhGZ9wjgQzcGOOeS9o15GftG/LiJ5vYcaDA7XBMBflT438VGFDG+EuBVs7rdmAcgIjEAi8549sBQ0Wk3bkEa4wJHU9e3p5YEX79zlp7dHOYiSuvgKouFJG0MooMBqaq55dfIiKJItIYSAM2q+pWABF5wym77mwC/e172azblX82k5oo1K5JbZ68vL3bYUS0JonVeOinrfnd++t4f81uLk9v4nZIxk+BaONPAXZ4fc51hpU23CcRuV1EskQkKy8vLwBhGWMq20290uiUWoffvpfNoYJCt8Mxfiq3xu8H8TFMyxjuk6pOACYAZGZm/qCc1d6MCT2xMcIzV3Xkir8v4o9z1vPc1Z3cDsn4IRA1/lygqdfnVGBXGcONMRGkfZM63PajFryZtYMvtuxzOxzjh0Ak/tnAjc7VPT2AQ6q6G1gOtBKR5iJSBbjeKWuMiTD3X9KKtKTqPPrvrzh20nrrCnX+XM45HVgMtBaRXBG5RURGi8hop8gcYCuwGZgI3AmgqkXA3cBHwHpghqpmV8IyGGNclhAfyzNXdWL7/gJemLvJ7XBMOfy5qmdoOeMVuKuUcXPw/GMwJuSIyADgRSAWmKSqz5YYL874gUABMFJVVzrjEoFJQAc8565uVtXFQQw/5PQ8P4mh3c5j0mdbGdixMRlNE90OyZTC7tw1UcnP+0x83qPieBH4UFXbAOl4jmqj3qMD29CwdgK/fGu1ddAewizxm2jVDec+E1U9CZy+z8TbmXtUVHUJkCgijUWkNnAR8AqAqp5U1YPBDD5U1U6I549XdeTrvUf42yeb3Q7HlMISv4lW/txnUlqZFkAeMEVEvhSRSSJSw9dMovH+lH6tG3B111TGLdjCV7mH3A7H+GCJ30Qrf+4zKa1MHNAFGKeqnYGjgM9nUanqBFXNVNXM5OTkc4k3rDxxWTvq16zCQ2+tsiafEGSJ30Qrf+4zKeselVxVXeoMn4nnH4Fx1KkWz7NXdWLTniO88N+v3Q7HlGCJ30Qrf+4z8XmPiqp+C+wQkdZOuf6c5TOoIlm/Ng24LrMpExZuYcX279wOx3ixxG+iUmn3mfhzj4rjHmCaiKwBMoA/Bi34MPLry9rSuE41HpqxioKTRW6HYxyBeFaPMWHJ130mqjre631Z96isAjIrNcAIUCshnr9ck87QiUt49oMN/G5wB7dDMliN3xhTyXqen8QtfZozdfF2FmyKjiubQp0lfmNMpfvlz1rTqkFNfvnWar47etLtcKKeJX5jTKVLiI/lhesy+K7gJI/N+sp67HKZJX5jTFB0SKnDAz+5gA/WfsvMFbluhxPVLPEbY4LmjovOp3vzejw1O5ucfUfdDidqWeI3xgRNbIzwwnUZxMYI9725isJTxW6HFJUs8RtjgqpJYjWeuaoTq3cc5IX/2rP73WCJ3xgTdIM6Nea6zKaMW7CFLzZbd43BZonfGOOKJ69oR4v6Nbj/zVXsP3LC7XCiiiV+Y4wrqleJ429Du3DwWCEPvbWa4mK7xDNYLPEbY1zTrkltfj2oLfM35vHK59vcDidqWOI3xrjqhh7NGNC+Ec99uIGV39hTPIPBEr8xxlUiwnNXd6JxYgL3/OtLDhbYIx0qmyV+Y4zr6lSL5+9Du7D38HEemmHt/ZXNEr8xJiSkN03k8YFt+WTDXl5euNXtcCKaJX5jTMi4qVcagzo15i8fb2TJ1v1uhxOxLPEbY0KGiPDckE40S6rO3f/6kr35x90OKSJZ4jfGhJSaVeMYP6IrR08Ucde/VtrzfCqBJX5jTMi5oGEtnh3SkeU53/HHOevdDifiWJ+7xpiQNDgjhVU7DjJlUQ4ZTRMZnJHidthdpqUAAA+ESURBVEgRw2r8xpiQ9djAtnRrXo+H317Dul35bocTMSzxG2NCVnxsDC8N60JitSrc/lqW9dcbIH4lfhEZICIbRWSziDziY3xdEZklImtEZJmIdPAa94CIZIvIWhGZLiIJgVwAY0xkS65VlXEjurA3/wR3T19JkZ3sPWflJn4RiQVeAi4F2gFDRaRdiWKPAatUtRNwI/CiM20KcC+QqaodgFjg+sCFb4yJBp3Pq8vvf96BRZv388wHG9wOJ+z5U+PvBmxW1a2qehJ4Axhcokw74BMAVd0ApIlIQ2dcHFBNROKA6sCugERujIkq12Y2ZWSvNF75fBtvZe1wO5yw5k/iTwG813KuM8zbauAqABHpBjQDUlV1J/AX4BtgN3BIVT8+16CNMdHp14Pa0rtlEo/PWsuK7fYkz7PlT+IXH8NKPkHpWaCuiKwC7gG+BIpEpC6eo4PmQBOghoiM8DkTkdtFJEtEsvLy8vxeAGNM9IhzTvY2Tkzgjtey2HnwmNshhSV/En8u0NTrcyolmmtUNV9VR6lqBp42/mRgG3AJsE1V81S1EPg30MvXTFR1gqpmqmpmcnLyWSyKMSYaJFavwis3ZXKisJhb/5nF0RNFbocUdvxJ/MuBViLSXESq4Dk5O9u7gIgkOuMAbgUWqmo+niaeHiJSXUQE6A/YbXjGmHPSskEt/jasMxu/zee+N1Zxyh7jXCHlJn5VLQLuBj7Ck7RnqGq2iIwWkdFOsbZAtohswHP1z33OtEuBmcBK4CtnfhMCvhTGmKjTt3UDnry8PXPX7+G5D+1Kn4rw65ENqjoHmFNi2Hiv94uBVqVM+yTw5DnEaIwxPt3UK40teUeYsHAraUk1GNb9PLdDCgv2rB5jTFj7zWXt+OZAAU+8u5bUutW46AI7R1gee2SDMSasxcXG8PdhXWjVoCZ3TlvJ+t32TJ/yWOI3xoS9mlXjmDLqQmpUjWXUlOXsPmSXeZbFEr8xJiI0rlONKSO7ceREEaOmLCf/eKHbIYUsS/zGmIjRrkltxo3owua9Rxjz+gpOFtkD3XyxxG+ilh9PnRURGeuMXyMiXbzG5YjIVyKySkSyghu5KcuPWiXz3JBOLNq8n1/OXE2xXeP/A3ZVj4lKXk+d/Qmeu9OXi8hsVV3nVexSPJcptwK6A+Ocv6f1U9V9QQrZVMCQrql8m3+cP3+0kQa1qvL4oJIPFI5ulvhNtDrz1FkAETn91FnvxD8YmKqqCixx7lBvrKq7gx+uqag7+57P3vzjTPxsGw1qJXDbRS3cDilkWFOPiVb+PHW2rDIKfCwiK0Tk9tJmYg8fdI+I8JvL2zOoU2P+MGc9b6/IdTukkGE1fhOt/HnqbFlleqvqLhFpAPxXRDao6sIfFFadgPOYkszMTGtsDrLYGOH5a9M5WHCSX729hjrV4rmkXcPyJ4xwVuM30arcp86WVUZVT//dC8zC03RkQlDVuFheviGT9k1qc9e/VrJ06363Q3KdJX4Trcp96qzz+Ubn6p4eeDoS2i0iNUSkFoCI1AB+CqwNZvCmYmpWjePVUd1IrVuNW/6ZxVe5h9wOyVWW+E1U8vOps3OArcBmYCJwpzO8IfC5iKwGlgH/UdUPg7oApsLq1ajC67d2p061eG6cvJSv9xx2OyTXiOeChdCSmZmpWVl2abSpHCKyQlUzgz1f265DQ86+o1zz8mIEeGt0T5ol1XA7pICoyHZtNX5jTFRJq1+D12/pzslTxQybuJRdUdh9oyV+Y0zUad2oFq/d3J38Y4UMn7SUvfnH3Q4pqCzxG2OiUsfUOrx6czf25B9n2KSl7Dtywu2QgsYSvzEmanVtVpfJIy8k97sCRkxayoGjJ90OKSgs8RtjolqPFkm8ctOFbNt3lBGTlvJdFCR/S/zGmKjXu2V9Jt6Yyea8I4x4ZSkHCyI7+VviN8YY4KILkplwQ1e+3nuEYRMju+Zvid8YYxx9Wzdgwg1d2Zx3hGER3OZvid8YY7z0bd2ASTdmsjXvCMMmLonIq30s8RtjTAkXXZDMKzddSM7+o1w/YUnEXedvid8YY3zo06o+r47qxq6Dx7j25cURdYevJX5jjClFjxZJvHZLN/YfOck14xezff9Rt0MKCEv8xhhThq7N6vGv23pQcLKIa8YvjoinelriN8aYcnRMrcObd/REgWtfXsya3INuh3ROLPEbY4wfLmhYi5mje1KjahzDJi5l8Zbw7cnLEr8xxvipWVINZo7uRaM6Cdw0ZRn/XbfH7ZDOiiV+Y4ypgEZ1EphxR0/aNqrF6NdXMHNFrtshVZhfiV9EBojIRhHZLCKP+BhfV0RmicgaEVkmIh28xiWKyEwR2SAi60WkZyAXwBhjgq1ejSpMu60HPVsk8Yu3VvPygi1uh1Qh5SZ+EYkFXgIuBdoBQ0WkXYlijwGrVLUTcCPwote4F4EPVbUNkI6nf1NjjAlrNavG8crITC7r1JhnPtjA799fR3Fx6HVl60ucH2W6AZtVdSuAiLwBDAbWeZVpBzwDoKobRCRNRBoCx4CLgJHOuJNAZD78whgTdarGxTL2+s7Ur1mVSZ9vY+/hE/z5mk5UjYt1O7Qy+dPUkwLs8Pqc6wzzthq4CkBEugHNgFSgBZAHTBGRL0Vkkoj47NlYRG4XkSwRycrLy6vgYhhjjDtiYoQnL2/HwwPaMHv1LkZNWU7+8UK3wyqTP4lffAwreTzzLFBXRFYB9wBfAkV4jii6AONUtTNwFPjBOQIAVZ2gqpmqmpmcnOxv/MYY4zoRYUzf83n+2nSWbTvAteMXs/tQ6D7iwZ/Enws09fqcCuzyLqCq+ao6SlUz8LTxJwPbnGlzVXWpU3Qmnn8ExhgTca7qksqro7qR+90xrnxpEdm7Drkdkk/+JP7lQCsRaS4iVYDrgdneBZwrd6o4H28FFjr/DL4FdohIa2dcf75/bsAYYyJKn1b1eWt0T2JEuHb8YuZv3Ot2SD9QbuJX1SLgbuAjPFfkzFDVbBEZLSKjnWJtgWwR2YDn6p/7vL7iHmCaiKwBMoA/BnIBjDEm1LRtXJtZd/amWVINbvlnFq8t2e52SN/jz1U9qOocYE6JYeO93i8GWpUy7Sog8xxiNMaYsNOoTgIzRvfk3ulf8sQ7a9mWd5THB7UlNsbXadPgsjt3jTGmktSsGsfEGzMZ1TuNyYu2cfvULI6cKHI7LEv8xhhTmWJjhCcvb8/TV3Zg/qY8rh73BTsOFLgakyV+Y4wJght6NOOfTo9eg19axLJtB1yLxRK/McYESZ9W9Xnnrt4kVotn+KQlvLHsG1fisMRvjDFB1CK5JrPu6k3P8+vzyL+/4jfvrqXwVHFQY7DEb4wxQVanWjxTRl7IbT9qztTF2xkxaSn7j5wI2vwt8RtjjAtiY4THB7Xjr9dlsGrHQS7/2+d8lRucO30t8RtjjIuu7JzC22N6ISIMGf8Fb2XtKH+ic2SJ3xhjXNYhpQ7v3dOHzGZ1+eXMNTw+6ytOFJ2qtPlZ4jfGmBBQr0YVpt7cjTsubsG0pd9w7ctL2Hmwcp7waYnfGGNCRFxsDI9e2pbxI7qwZe8RLhv7GQs2Bb5/Ekv8Jmr50Ze0iMhYZ/waEelSYnys08HQ+8GL2kSDAR0aM/vu3jSolcDIKct4/r+bOBXAbh0t8Zuo5Gdf0pfiefhgK+B2YFyJ8fdhfUibStIiuSbv3NWbn3dOYewnX3Pj5KXkHQ7MJZ+W+E20OtOXtNMX9Om+pL0NBqaqxxIgUUQaA4hIKjAImBTMoE10qVYllv+7Jp0/DelEVs53DBz7GWt3nvsln5b4TbTypy/pssr8FfgVUOYtl9aXtDlXIsK1Fzbl3bt706ZRLVISq53zd1riN9HKn76kfZYRkcuAvaq6oryZWF/SJlDaNKrNa7d0p26NKuUXLoclfhOtyu1LuowyvYErRCQHTxPRj0Xk9coL1ZjAssRvolW5fUk7n290ru7pARxS1d2q+qiqpqpqmjPdp6o6IqjRG3MO/Op60ZhIo6pFInK6L+lYYPLpvqSd8ePxdDc6ENgMFACj3IrXmECyxG+ilh99SStwVznfMR+YXwnhGVNprKnHGGOijCV+Y4yJMpb4jTEmyljiN8aYKCOe81ehRUTygO0+RtUH9gU5nNJYLL6FQyzNVDXod1OVsV1DeKw3N1gsvvmKxe/tOiQTf2lEJEtVM92OAyyW0lgsZyeUYrVYfIukWKypxxhjoowlfmOMiTLhlvgnuB2AF4vFN4vl7IRSrBaLbxETS1i18RtjjDl34VbjN8YYc44s8RtjTJQJm8RfXsfYlTzvpiIyT0TWi0i2iNznDH9KRHaKyCrnNTBI8eSIyFfOPLOcYfVE5L8i8rXzt24Q4mjtteyrRCRfRO4P1noRkckisldE1noNK3U9iMijzvazUUR+VhkxnQ23tm3brkuNI/K3a1UN+Reex+ZuAVoAVYDVQLsgzr8x0MV5XwvYhKeD7qeAX7iwPnKA+iWG/Ql4xHn/CPCcC7/Rt0CzYK0X4CKgC7C2vPXg/F6rgapAc2d7ig32b1fKenNl27bt2u/fJ+K263Cp8fvTMXalUU/nGyud94eB9fywf1a3DQb+6bz/J3BlkOffH9iiqqXdmRpwqroQOFBicGnrYTDwhqqeUNVteJ6x3y0ogZbNtW3btmu/ROR2HS6J35+OsYNCRNKAzsBSZ9DdIrLGOTyr9MNQhwIfi8gKEbndGdZQVXeDZ4cGGgQpltOuB6Z7fXZjvUDp6yFktqESQiIu265LFZHbdbgkfn86xq78IERqAm8D96tqPjAOOB/IAHYD/xekUHqrahfgUuAuEbkoSPP1STxdF14BvOUMcmu9lCUktiEfXI/LtmvfInm7DpfE70/H2JVKROLx7BzTVPXfAKq6R1VPqWoxMJEgNR2o6i7n715gljPfPSLS2Im1MbA3GLE4LgVWquoeJy5X1oujtPXg+jZUClfjsu26TBG7XYdL4venY+xKIyICvAKsV9XnvYY39ir2c2BtyWkrIZYaIlLr9Hvgp858ZwM3OcVuAt6t7Fi8DMXrcNiN9eKltPUwG7heRKqKSHOgFbAsiHGVxrVt27brckXudh3MM+TneKZ7IJ6rDrYAjwd53n3wHD6tAVY5r4HAa8BXzvDZQOMgxNICz1n81UD26XUBJAGfAF87f+sFad1UB/YDdbyGBWW94NkpdwOFeGo+t5S1HoDHne1nI3BpMLehcpbDlW3btuvo3a7tkQ3GGBNlwqWpxxhjTIBY4jfGmChjid8YY6KMJX5jjIkylviNMSbKWOI3xpgoY4nfGGOizP8DW+mpFR2NMG4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input the number of test alphabet:5\n",
      "input test alphabet:e\n",
      "e->a\n",
      "input test alphabet:a\n",
      "a->b\n",
      "input test alphabet:c\n",
      "c->d\n",
      "input test alphabet:d\n",
      "d->e\n",
      "input test alphabet:c\n",
      "c->d\n"
     ]
    }
   ],
   "source": [
    "# 用RNN实现输入一个字母，预测下一个字母 （One hot 编码）\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Dense, SimpleRNN\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "\n",
    "input_word = \"abcde\"\n",
    "w_to_id = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}  # 单词映射到数值id的词典\n",
    "id_to_onehot = {0: [1., 0., 0., 0., 0.], 1: [0., 1., 0., 0., 0.], 2: [0., 0., 1., 0., 0.], 3: [0., 0., 0., 1., 0.],\n",
    "                4: [0., 0., 0., 0., 1.]}  # id编码为one-hot\n",
    "\n",
    "x_train = [id_to_onehot[w_to_id['a']], id_to_onehot[w_to_id['b']], id_to_onehot[w_to_id['c']],\n",
    "           id_to_onehot[w_to_id['d']], id_to_onehot[w_to_id['e']]]\n",
    "y_train = [w_to_id['b'], w_to_id['c'], w_to_id['d'], w_to_id['e'], w_to_id['a']]\n",
    "\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(x_train)\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(y_train)\n",
    "tf.random.set_seed(7)\n",
    "\n",
    "# 使x_train符合SimpleRNN输入要求：[送入样本数， 循环核时间展开步数， 每个时间步输入特征个数]。\n",
    "# 此处整个数据集送入，送入样本数为len(x_train)；输入1个字母出结果，循环核时间展开步数为1; 表示为独热码有5个输入特征，每个时间步输入特征个数为5\n",
    "x_train = np.reshape(x_train, (len(x_train), 1, 5))\n",
    "y_train = np.array(y_train)\n",
    "\n",
    "model = tf.keras.Sequential([\n",
    "    SimpleRNN(3),#三个记忆体，个数越多，记忆力越好，占用资源越多\n",
    "    Dense(5, activation='softmax')#映射到独热码编码，找到最大概率的字母\n",
    "])\n",
    "\n",
    "model.compile(optimizer=tf.keras.optimizers.Adam(0.01),\n",
    "              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),\n",
    "              metrics=['sparse_categorical_accuracy'])\n",
    "\n",
    "checkpoint_save_path = \"./checkpoint/rnn_onehot_1pre1.ckpt\"\n",
    "\n",
    "if os.path.exists(checkpoint_save_path + '.index'):\n",
    "    print('-------------load the model-----------------')\n",
    "    model.load_weights(checkpoint_save_path)\n",
    "\n",
    "cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,\n",
    "                                                 save_weights_only=True,\n",
    "                                                 save_best_only=True,\n",
    "                                                 monitor='loss')  # 由于fit没有给出测试集，不计算测试集准确率，根据loss，保存最优模型\n",
    "\n",
    "history = model.fit(x_train, y_train, batch_size=32, epochs=100, callbacks=[cp_callback])\n",
    "\n",
    "model.summary()\n",
    "\n",
    "# print(model.trainable_variables)\n",
    "file = open('./weights.txt', 'w')  # 参数提取\n",
    "for v in model.trainable_variables:\n",
    "    file.write(str(v.name) + '\\n')\n",
    "    file.write(str(v.shape) + '\\n')\n",
    "    file.write(str(v.numpy()) + '\\n')\n",
    "file.close()\n",
    "\n",
    "###############################################    show   ###############################################\n",
    "\n",
    "# 显示训练集和验证集的acc和loss曲线\n",
    "acc = history.history['sparse_categorical_accuracy']\n",
    "loss = history.history['loss']\n",
    "\n",
    "plt.subplot(1, 2, 1)\n",
    "plt.plot(acc, label='Training Accuracy')\n",
    "plt.title('Training Accuracy')\n",
    "plt.legend()\n",
    "\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(loss, label='Training Loss')\n",
    "plt.title('Training Loss')\n",
    "plt.legend()\n",
    "plt.show()\n",
    "\n",
    "############### predict #############\n",
    "\n",
    "preNum = int(input(\"input the number of test alphabet:\"))\n",
    "for i in range(preNum):\n",
    "    alphabet1 = input(\"input test alphabet:\")\n",
    "    alphabet = [id_to_onehot[w_to_id[alphabet1]]]\n",
    "    # 使alphabet符合SimpleRNN输入要求：[送入样本数， 循环核时间展开步数， 每个时间步输入特征个数]。\n",
    "    # 此处验证效果送入了1个样本，送入样本数为1；输入1个字母出结果，所以循环核时间展开步数为1; 表示为独热码有5个输入特征，每个时间步输入特征个数为5\n",
    "    alphabet = np.reshape(alphabet, (1, 1, 5))\n",
    "    result = model.predict([alphabet])\n",
    "    pred = tf.argmax(result, axis=1)\n",
    "    pred = int(pred)\n",
    "    tf.print(alphabet1 + '->' + input_word[pred])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 计算过程:输入4个字母，预测下一个字母\n",
    "                                          yt[0.71  0.14  0.10  0.05  0.00]    # out:a\n",
    "                                          \n",
    "                                                   ⬆by [-0.3  0.2  0.1  0.1  -0.3]\n",
    "                                          Why \n",
    "                                          [[-1.3  0.5  -0.7  -0.2  0.8]\n",
    "                                          [-1.4 -0.8  -1.2   0.9  1.4]\n",
    "                                          [ 0.7  1.1  -1.2   1.3 -1.1]]\n",
    "                  Whh \n",
    "                  [[-0.9   -0.9   -0.9] \n",
    "                  [ 0.5    0.9   -0.3] \n",
    "                  [ 1.0    0.3   -1.5]]                  ⬆\n",
    "    ht[-0.9,0.2,0.2] →                 →[···]→···→[-1.0,-1.0,0.8]\n",
    "    \n",
    "    ⬆bh[0.2,0.0,-0.1]\n",
    "    \n",
    "    Wxh\n",
    "    [[ 1.2  -1.3   1.1]\n",
    "    [-1.5   0.2   0.3]\n",
    "    [-0.3   1.7   0.7]\n",
    "    [-0.1   0.1  -0.1]\n",
    "    [-1.2  -1.5   0.3]]\n",
    "\n",
    "    ⬆                   ⬆             ⬆             ⬆ \n",
    "    xt[0,1,0,0,0] #in:b  xt[0,0,1,0,0] #in:c  xt[0,0,0,1,0] #in:d  xt[0,0,0,0,1] #in:e"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-------------load the model-----------------\n",
      "Train on 5 samples\n",
      "Epoch 1/100\n",
      "5/5 [==============================] - 2s 359ms/sample - loss: 0.5665 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 2/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.5552 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 3/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.5441 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 4/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.5333 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 5/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.5226 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 6/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.5122 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 7/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.5020 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 8/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.4921 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 9/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.4823 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 10/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.4728 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 11/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.4634 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 12/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.4543 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 13/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.4454 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 14/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.4366 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 15/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.4281 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 16/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.4197 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 17/100\n",
      "5/5 [==============================] - 0s 20ms/sample - loss: 0.4116 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 18/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.4036 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 19/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.3959 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 20/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.3883 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 21/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.3809 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 22/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.3736 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 23/100\n",
      "5/5 [==============================] - 0s 34ms/sample - loss: 0.3666 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 24/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.3597 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 25/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.3530 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 26/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.3464 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 27/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.3400 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 28/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.3338 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 29/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.3277 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 30/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.3218 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 31/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.3161 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 32/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.3104 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 33/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.3049 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 34/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.2996 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 35/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.2944 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 36/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.2893 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 37/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.2844 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 38/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.2795 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 39/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.2748 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 40/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.2703 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 41/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.2658 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 42/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.2614 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 43/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.2572 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 44/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.2530 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 45/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.2490 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 46/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.2451 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 47/100\n",
      "5/5 [==============================] - 0s 23ms/sample - loss: 0.2412 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 48/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.2375 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 49/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.2338 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 50/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.2302 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 51/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.2268 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 52/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.2234 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 53/100\n",
      "5/5 [==============================] - 0s 42ms/sample - loss: 0.2200 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 54/100\n",
      "5/5 [==============================] - 0s 23ms/sample - loss: 0.2168 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 55/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.2136 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 56/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.2106 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 57/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.2075 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 58/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.2046 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 59/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.2017 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 60/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1989 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 61/100\n",
      "5/5 [==============================] - 0s 30ms/sample - loss: 0.1962 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 62/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.1935 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 63/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.1909 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 64/100\n",
      "5/5 [==============================] - 0s 17ms/sample - loss: 0.1883 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 65/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1858 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 66/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1833 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 67/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1809 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 68/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1786 - sparse_categorical_accuracy: 1.0000\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 69/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.1763 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 70/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.1740 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 71/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.1718 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 72/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.1697 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 73/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1676 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 74/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1655 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 75/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.1635 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 76/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1615 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 77/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1595 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 78/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1576 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 79/100\n",
      "5/5 [==============================] - 0s 15ms/sample - loss: 0.1558 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 80/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.1540 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 81/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1522 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 82/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1504 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 83/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1487 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 84/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.1470 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 85/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1453 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 86/100\n",
      "5/5 [==============================] - 0s 11ms/sample - loss: 0.1437 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 87/100\n",
      "5/5 [==============================] - 0s 13ms/sample - loss: 0.1421 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 88/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1405 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 89/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1390 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 90/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1375 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 91/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1360 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 92/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1346 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 93/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.1331 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 94/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1317 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 95/100\n",
      "5/5 [==============================] - 0s 14ms/sample - loss: 0.1303 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 96/100\n",
      "5/5 [==============================] - 0s 12ms/sample - loss: 0.1290 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 97/100\n",
      "5/5 [==============================] - 0s 30ms/sample - loss: 0.1277 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 98/100\n",
      "5/5 [==============================] - 0s 19ms/sample - loss: 0.1264 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 99/100\n",
      "5/5 [==============================] - 0s 16ms/sample - loss: 0.1251 - sparse_categorical_accuracy: 1.0000\n",
      "Epoch 100/100\n",
      "5/5 [==============================] - 0s 18ms/sample - loss: 0.1238 - sparse_categorical_accuracy: 1.0000\n",
      "Model: \"sequential_4\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "simple_rnn_4 (SimpleRNN)     multiple                  27        \n",
      "_________________________________________________________________\n",
      "dense_4 (Dense)              multiple                  20        \n",
      "=================================================================\n",
      "Total params: 47\n",
      "Trainable params: 47\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEICAYAAABYoZ8gAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3dd3xUZdr/8c+VAhg6SWhJEBCkkwABFBBBLFgQXCwoqOjacNe+a31c3cf10fV5frqya1n7urLYVhRdBBZpKkgvEnqJJvQauhBy//6YAxvDpACTnJnM9/16zStnTr3mzH2uObnPOfdtzjlERCR6xPgdgIiIVCwlfhGRKKPELyISZZT4RUSijBK/iEiUUeIXEYkySvwnycy+NLMbQz2vSKTSMRE5LJru4zezvYXeJgA/AUe897c750ZVfFSnzsyaAWuAV51zd/odj0SOynZMmFkf4D3nXKrfsYSzqDrjd87VOPoCfgQGFBp3rICbWZx/UZ6UG4CdwBAzq1qRGzaz2IrcnoRWJT4mpARRlfiLY2Z9zCzXzB4ys03A22ZW18y+MLOtZrbTG04ttMxUM7vFGx5uZt+Y2f95864zs4tPct5mZjbdzPaY2SQze8nM3ivlI9wA/BdwGBhQ5LMNNLOFZrbbzNaYWX9vfD0ze9vMNnhxfFo4viLrcGbWwht+x8xeMbNxZrYP6Gtml5rZAm8bOWb2ZJHle5nZDDPb5U0fbmZdzWxz4YRiZoPNbGEpn1UqQCU4JoJ9pjbedneZWZaZXV5o2iVmttTbxnoz+403Psn7nLvMbIeZfW1mEZ83I/4DhFBDoB5wOnAbgX3ztve+CXAA+EsJy3cHVgBJwHPAm2ZmJzHvP4DZQCLwJHB9SUGb2TlAKvA+8CGBH4Gj07oB7wK/BeoAvYFsb/LfCfxr3w6oD7xQ0naKuA54GqgJfAPs87ZbB7gUGGFmg7wYmgBfAn8GkoEMYKFzbg6wHbig0HqHeXFJeIjIYyIYM4sHPgcmEijvdwGjzKyVN8ubBKq2agLtgcne+AeAXAJltwHwKBD59ePOuah8EUiA53vDfYBDQLUS5s8AdhZ6PxW4xRseDqwuNC2BQOFoeCLzEjiY8oGEQtPfI1BnWVxcbwCfesNnEzjrr++9/yvwQpBlGgEFQN0g04YD3xQZ54AW3vA7wLul7Ns/Hd0u8Agwppj5HgJGecP1gP1AI7/LRrS+KsMx4cWdG2T8OcAmIKbQuNHAk97wj8DtQK0iy/038NnR8l9ZXjrj/4+tzrmDR9+YWYKZ/dXMfjCz3cB0oI4VX6e96eiAc26/N1jjBOdtDOwoNA4gp7iAzew04CpglLeumQQK8HXeLGkELvoWleZtZ2dx6y7Fz2Iys+5mNsWrAsgD7iBw5lZSDBA4gAeYWQ3gauBr59zGk4xJQi/ijokSNAZynHMFhcb9AKR4w4OBS4AfzGyamZ3tjf9fYDUw0czWmtnDJ7HtsKPE/x9F/317AGgFdHfO1SJQTQJQ3L+qobARqGdmCYXGpZUw/xVALeBlM9vk1cWm8J/qnhzgjCDL5XjbqRNk2j4CZ1wAmFnDIPMU3Vf/AMYCac652sCr/Gc/FRcDzrn1wEzvc1yPqnnCTSQeE8XZAKQVqZ9vAqwHcM7Ncc4NJFAN9CmBalOcc3uccw8455oTuH52v5n1O4nthxUl/uLVJFCHucvM6gFPlPcGnXM/AHOBJ82sinfWMaCERW4E3gI6EPi3OwPoCWSYWQcC9ZY3mVk/M4sxsxQza+2dVX9J4AejrpnFm9nRg3gR0M7MMsysGoE61dLUJHBWdtC7rnBdoWmjgPPN7GozizOzRDPLKDT9XeBB7zOMKcO2xD+RcEwAYGbVCr8IXCPYBzzolfc+3nre99Y71MxqO+cOA7vxbmk1s8vMrIV3veHo+CNBNxpBlPiL9yfgNGAb8B0wvoK2O5RAXf124A/ABwTurf4ZM0sB+gF/cs5tKvSa58V6o3NuNnATgQu3ecA0AhfmIHCGfRhYDmwB7gVwzq0kUK85CVhF4OJtae4E/tvM9gC/wztb8tb3I4F/oR8AdgALgfRCy47xYhrjnNtXhm2Jf8L6mCgkhcAPVOFXGnA5cDGB+F8GbnDOLfeWuR7I9qqw7iBwowFASwLHwl4C/52+7JybGqoP5peoeoArEpnZB8By51y5n135xczWELijYpLfsUj4i4ZjorzpjD/MWOD+9jO8qpn+wEACdY6VkpkNJlCXPLm0eSU6RdsxURH0NF74aQh8QuCe5VxghHNugb8hlQ8zmwq0Ba4vcreFSGFRc0xUFFX1iIhEGVX1iIhEmbCs6klKSnJNmzb1OwyppObNm7fNOZdc0dtVuZbydCLlOiwTf9OmTZk7d67fYUglZWY/+LFdlWspTydSrlXVIyISZZT4RUSijBK/iEiUCcs6/vJy+PBhcnNzOXjwYOkzS8SrVq0aqampxMfH+x1KxNOxEz5CUa6jKvHn5uZSs2ZNmjZtSvH9QUhl4Jxj+/bt5Obm0qxZM7/DiXg6dsJDqMp1VFX1HDx4kMTERBXcKGBmJCYm6gw1RHTshIdQleuoSvyACm4U0XcdWtqf4SEU30PUJX6RcDMxaxNvfL3W7zAkiijxV6Dt27eTkZFBRkYGDRs2JCUl5dj7Q4cOlbjs3Llzufvuu0vdRo8ePUIVLgD33HMPKSkpFBSoDbXyMmXFFl6ctIrDR7SPixNJx87UqVO57LLLQrKu8hJVF3f9lpiYyMKFCwF48sknqVGjBr/5zW+OTc/PzycuLvhXkpmZSWZmZqnbmDFjRmiCBQoKChgzZgxpaWlMnz6dPn36hGzdhR05coTY2OK6ba38erdMZvTsHBbm7KJr03p+hxOWIu3YCXc64/fZ8OHDuf/+++nbty8PPfQQs2fPpkePHnTq1IkePXqwYsUK4OdnEU8++SQ333wzffr0oXnz5owcOfLY+mrUqHFs/j59+nDllVfSunVrhg4dytGWWMeNG0fr1q3p1asXd999d7FnJ1OmTKF9+/aMGDGC0aNHHxu/efNmrrjiCtLT00lPTz92wLz77rt07NiR9PR0rr/++mOf7+OPPw4aX9++fbnuuuvo0KEDAIMGDaJLly60a9eO11577dgy48ePp3PnzqSnp9OvXz8KCgpo2bIlW7duBQI/UC1atGDbtm0n+zX4qkeLJGJjjOkrt/odSkQJ52MnmNGjR9OhQwfat2/PQw89BAROeoYPH0779u3p0KEDL7zwAgAjR46kbdu2dOzYkSFDhpz6zioias/4f/95Fks37A7pOts2rsUTA9qd8HIrV65k0qRJxMbGsnv3bqZPn05cXByTJk3i0Ucf5Z///OdxyyxfvpwpU6awZ88eWrVqxYgRI467r3fBggVkZWXRuHFjevbsybfffktmZia3334706dPp1mzZlx77bXFxjV69GiuvfZaBg4cyKOPPsrhw4eJj4/n7rvv5txzz2XMmDEcOXKEvXv3kpWVxdNPP823335LUlISO3bsKPVzz549myVLlhy7Le2tt96iXr16HDhwgK5duzJ48GAKCgq49dZbj8W7Y8cOYmJiGDZsGKNGjeLee+9l0qRJpKenk5SUdIJ7PjzUPi2ejLQ6TF+5lQcubOV3OKXSsVP6sVPUhg0beOihh5g3bx5169blwgsv5NNPPyUtLY3169ezZMkSAHbt2gXAs88+y7p166hateqxcaGkM/4wcNVVVx2r6sjLy+Oqq66iffv23HfffWRlZQVd5tJLL6Vq1aokJSVRv359Nm/efNw83bp1IzU1lZiYGDIyMsjOzmb58uU0b978WLItrvAeOnSIcePGMWjQIGrVqkX37t2ZOHEiAJMnT2bEiBEAxMbGUrt2bSZPnsyVV155LPnWq1d6lUW3bt1+di/yyJEjSU9P56yzziInJ4dVq1bx3Xff0bt372PzHV3vzTffzLvvvgsEfjBuuummUrcXznq3TGbx+jx27Cu5vlp+LhyPnWDmzJlDnz59SE5OJi4ujqFDhzJ9+nSaN2/O2rVrueuuuxg/fjy1atUCoGPHjgwdOpT33nuv2CqsUxG1Z/wnc3ZRXqpXr35s+PHHH6dv376MGTOG7OzsYuvVq1atemw4NjaW/Pz8Ms1T1o53xo8fT15e3rFqmP3795OQkMCll14adH7nXNDbzOLi4o5dGHbO/exCXOHPPXXqVCZNmsTMmTNJSEigT58+HDx4sNj1pqWl0aBBAyZPnsysWbMYNWpUmT5XuOp9ZhIvTFrJ16u2MjAjxe9wSqRj58QVt2zdunVZtGgREyZM4KWXXuLDDz/krbfe4l//+hfTp09n7NixPPXUU2RlZYX0B0Bn/GEmLy+PlJTAgf/OO++EfP2tW7dm7dq1ZGdnA/DBBx8EnW/06NG88cYbZGdnk52dzbp165g4cSL79++nX79+vPLKK0CgjnL37t3069ePDz/8kO3btwMcq+pp2rQp8+bNA+Czzz7j8OHDQbeXl5dH3bp1SUhIYPny5Xz33XcAnH322UybNo1169b9bL0At9xyC8OGDePqq6+O+IvDHVPrUCchnukrI/M6RTgIl2MnmO7duzNt2jS2bdvGkSNHGD16NOeeey7btm2joKCAwYMH89RTTzF//nwKCgrIycmhb9++PPfcc+zatYu9e/eG9LMo8YeZBx98kEceeYSePXty5MiRkK//tNNO4+WXX6Z///706tWLBg0aULt27Z/Ns3//fiZMmPCzs/vq1avTq1cvPv/8c1588UWmTJlChw4d6NKlC1lZWbRr147HHnuMc889l/T0dO6//34Abr31VqZNm0a3bt2YNWvWz87QCuvfvz/5+fl07NiRxx9/nLPOOguA5ORkXnvtNX7xi1+Qnp7ONddcc2yZyy+/nL1790Z8NQ9AbIxxTstkpq3cSkGBukM9GeFw7Bz11VdfkZqaeuyVnZ3NM888Q9++fUlPT6dz584MHDiQ9evX06dPHzIyMhg+fDjPPPMMR44cYdiwYXTo0IFOnTpx3333UadOndB+GOdc2L26dOniysPSpUvLZb2RZs+ePc455woKCtyIESPc888/73NEJ2fOnDmuV69eJc4T7DsH5rowLNcfzc1xpz/0hfs+d1dpH73C6dgJCJdj51TLtc74o9Drr79ORkYG7dq1Iy8vj9tvv93vkE7Ys88+y+DBg3nmmWf8DiVkep8ZuDA+Tbd1hq3KcOwAmDuFCxblJTMz05VHF3XLli2jTZs2IV+vhK9g37mZzXPOlf5ET4iVpVxfOvJrEqrE8tEdoX0C+1Tp2Akvp1quo+6MPxx/6KR8ROJ33bdVfeb/uIu8/cEvgvspEvdnZRSK7yGqEn+1atXYvn27CnAUcF675dWqVfM7lBPSt3UyRwocX68Or+oeHTvhIVTlOqru409NTSU3N/fYo/5SuR3tqSiSZKTVpU5CPFOWb+Wyjo39DucYHTvhIxTlOqoSf3x8vHpjkrAWG2P0bpnMtJVbKChwxMSERxv4OnYql6iq6hGJBH1bJ7Nt7yG+X5/ndyhSSSnxi4SZc8+sjxlMXr7F71Ckkio18ZvZW2a2xcyWFDPdzGykma02s8Vm1rnI9FgzW2BmX4QqaJHKrF71KnRKq8OUFUr8Uj7Kcsb/DtC/hOkXAy29123AK0Wm3wMsO5ngRKJVvzYNWJybx5bd6ixeQq/UxO+cmw6U1Lj6QOBd76nh74A6ZtYIwMxSgUuBN0IRrEi06NuqPoDO+qVchKKOPwXIKfQ+1xsH8CfgQaDUzkTN7DYzm2tmc3XLmES7No1q0rh2Nb5apsQvoReKxB/sfjNnZpcBW5xz88qyEufca865TOdcZnJycgjCEolcZsZ5berz9aptHDwc+pYmJbqFIvHnAmmF3qcCG4CewOVmlg28D5xnZu+FYHsiUaFfmwYcOHyEmWu3+x2KVDKhSPxjgRu8u3vOAvKccxudc48451Kdc02BIcBk59ywEGxPJCqc3TyRhCqxfLXs+K4BRU5FWW7nHA3MBFqZWa6Z/dLM7jCzO7xZxgFrgdXA68Cd5RatSBSpFh9LrxZJTFq6RW3kSEiV2mSDc67EHoW9DgB+Vco8U4GpJxKYiMD5bRswcelmsjbspn1K8N6eRE6UntwVCWP9WtcnxmDiUlX3SOgo8YsEYWb9zWyF90T6w0Gm9zGzPDNb6L1+Vx5xJNaoSpfT6/JvJX4JISV+kSLMLBZ4icBT6W2Ba82sbZBZv3bOZXiv/y6veM5v04BlG3eTu3N/eW1CoowSv8jxugGrnXNrnXOHCNyOPNCvYC5s1xBAZ/0SMkr8Iscr6Wn0ws42s0Vm9qWZtQu2olA8kd4sqTot69dgQtamk1pepCglfpHjBX0avcj7+cDpzrl04M/Ap8FWFKon0i9q15DZ63awc9+hk16HyFFK/CLHK+5p9GOcc7udc3u94XFAvJkllVdAF7ZrQIGDSXqYS0JAiV/keHOAlmbWzMyqEHjyfGzhGcysoZmZN9yNwLFUbm0rdEipTePa1ZiQpcQvpy6q+twVKQvnXL6Z/RqYAMQCbznnso4+re6cexW4EhhhZvnAAWCIK8fHa82MC9s1ZPTsH9n3Uz7Vq+rQlZOn0iMShFd9M67IuFcLDf8F+EtFxtS/fUPemZHNtJVbuaRDo4rctFQyquoRiRBdm9YjsXoVxi/R3T1yapT4RSJEbIxxQdsGTF6+hZ/y1Ua/nDwlfpEI0r99Q/b+lM83q7b5HYpEMCV+kQjS44wkalWLY9z3qu6Rk6fELxJBqsTFcEHbhvx76SYO5ZfalbVIUEr8IhHmkg4N2X0wnxlrVN0jJ0eJXyTC9GqZRM2qcYz7fqPfoUiEUuIXiTBV42I5v20DJmRtVnWPnBQlfpEIdGmHRuQdOMy3qu6Rk6DELxKBzjkzUN3zr8Wq7pETp8QvEoGqxsVyQbsGTMjapIe55IQp8YtEqAEdG7PnYD5fr1R1j5wYJX6RCNWzRRJ1EuL5fPGG0mcWKUSJXyRCVYmL4eL2DZm0dDMHDqm6R8pOiV8kgg3o2Jh9h44wefkWv0ORCKLELxLBujdPJLlmVcYuWu93KBJBlPhFIlhsjHFZx0ZMWb6VvAOH/Q5HIoQSv0iEG5iRwqEjBUxQBy1SRkr8IhEuPbU2pycm8OlCVfdI2Sjxi0Q4M2NgRgoz125nU95Bv8ORCFBq4jezt8xsi5ktKWa6mdlIM1ttZovNrLM3Ps3MppjZMjPLMrN7Qh28iAQMymiMc+gir5RJWc743wH6lzD9YqCl97oNeMUbnw884JxrA5wF/MrM2p58qCJSnObJNUhPq8OYBXqYS0pXauJ3zk0HdpQwy0DgXRfwHVDHzBo55zY65+Z769gDLANSQhG0iBzviozGLNu4m+WbdvsdioS5UNTxpwA5hd7nUiTBm1lToBMwKwTbE5EgBqQ3Ji7GGDNf1T1SslAkfgsyzh2baFYD+Cdwr3Ou2FMRM7vNzOaa2dytW7eGICyR6JJYoyp9WtVnzIL1HClwpS8gUSsUiT8XSCv0PhXYAGBm8QSS/ijn3CclrcQ595pzLtM5l5mcnByCsESiz+DOKWzZ8xPfrFaLnVK8UCT+scAN3t09ZwF5zrmNZmbAm8Ay59zzIdiOiJTivDb1qX1aPJ/Mz/U7FAljcaXNYGajgT5AkpnlAk8A8QDOuVeBccAlwGpgP3CTt2hP4HrgezNb6I171Dk3LpQfQET+o2pcLJenN+bDuTnsPniYWtXi/Q5JwlCpid85d20p0x3wqyDjvyF4/b+IlKMru6Ty9+9+4F+LN3JttyZ+hyNhSE/uilQyHVNr07J+DT6am1P6zBKVlPhFKhkz46rMVOb/uIvVW/b6HY6EISV+kUroik6pxMaYzvolKCV+kUoouWZVzmtdn3/OX8/hIwV+hyNhRolfpJK6OjONbXt/Yoq6ZZQilPhFKqm+rZKpX7Mq789RdY/8nBK/SBBm1t/MVnjNjT9cwnxdzeyImV1ZkfGVRVxsDFdlpjJ1xRY25h3wOxwJI0r8IkWYWSzwEoEmx9sC1wZrUtyb74/AhIqNsOyuyWxCgYOP5upJXvkPJX6R43UDVjvn1jrnDgHvE2h+vKi7CLRFFbaV6E0SEzinZRLvz/5RDbfJMUr8IscrS1PjKcAVwKsVGNdJua5bEzbkHWTayrD9fZIKpsQvcrwSmxr3/Al4yDl3pMQVhUFz4+e3bUBSjar8Y9aPvmxfwo8Sv8jxim1qvJBM4H0zywauBF42s0FFVxQOzY3Hx8ZwTddUJi/fwvpdusgrSvwiwcwBWppZMzOrAgwh0Pz4Mc65Zs65ps65psDHwJ3OuU8rPtSyubZbExwwWmf9ghK/yHGcc/nArwncrbMM+NA5l2Vmd5jZHf5Gd3JS6yZwXqv6vD8nh0P5epI32inxiwThnBvnnDvTOXeGc+5pb9yrXh8URecd7pz7uOKjPDHDzj6dbXt/YkLWJr9DEZ8p8YtEiXNbJtOkXgLvzsz2OxTxmRK/SJSIiTGuP+t05mTvJGtDnt/hiI+U+EWiyNWZaVSLj+HdGT/4HYr4SIlfJIrUTojnik4pfLpwPTv3HfI7HPGJEr9IlBneoxk/5Rcweo5u7YxWSvwiUaZVw5r0OCORv8/8QZ20RCklfpEodFPPZmzMO8j4Jbq1Mxop8YtEoX6t69M0MYE3v1nndyjiAyV+kSgUE2Pc3KsZC3N2Me+HnX6HIxVMiV8kSl3ZJZXap8Xzxtdr/Q5FKpgSv0iUSqgSx9DuTRiftYkftu/zOxypQEr8IlFseI+mxMfE8MbXquuPJkr8IlGsfq1qDOrUmI/m5bB9709+hyMVRIlfJMrd1rs5Bw8X8LeZasYhWijxi0S5FvVrckHbBrw7M5t9P+X7HY5UACV+EWFEnzPYtf8wo2erGYdoUGriN7O3zGyLmS0pZrqZ2UgzW21mi82sc6Fp/c1shTft4VAGLiKh07lJXc5qXo/Xv17LT/kl9h8vlUBZzvjfAfqXMP1ioKX3ug14BcDMYoGXvOltgWvNrO2pBCsi5edXfVuwefdPfDJ/vd+hSDmLK20G59x0M2tawiwDgXedcw74zszqmFkjoCmw2jm3FsDM3vfmXXoygf7+8yyWbth9MotKFGrbuBZPDGjndxgRpVeLJDqm1uaVqWu4qksqcbGqCa6sQvHNpgA5hd7neuOKGx+Umd1mZnPNbO7WrVtDEJaInAgz467zWvLjjv18tnCD3+FIOSr1jL8MLMg4V8L4oJxzrwGvAWRmZh43n87eRMrf+W3q06ZRLV6asppBnVKIjQl2GEukC8UZfy6QVuh9KrChhPEiEqbMjLvPa8Habfv4fJEO18oqFIl/LHCDd3fPWUCec24jMAdoaWbNzKwKMMSbV0TC2EXtGtK6YU1GfrWKIwXF/pMuEawst3OOBmYCrcws18x+aWZ3mNkd3izjgLXAauB14E4A51w+8GtgArAM+NA5l1UOn0FEQigmxrinX0vWbtvH2EW6w6cyKstdPdeWMt0Bvypm2jgCPwwiEkEuateQNo1q8eKkVQzo2Fh3+FQy+jZF5DgxMcb9F5xJ9vb9uq+/ElLiF5Ggzm9Tn/TU2rz41So9zVvJKPGLSFBmxm8uasX6XQf4xyy14VOZKPGLSLF6tUji7OaJ/GXyarXcWYko8YtIscyMB/u3Yvu+Q+qlqxJR4heREnVqUpf+7Rry2vQ1bFMvXZWCEr+IlOq3/VtxML+AkV+t8jsUCQElfhEp1RnJNRjSNY1/zPqRNVv3+h2OnCIlfhEpk3vPP5OqcTE8++Vyv0ORU6TELyJlklyzKnf2bcG/l25m5prtfocjp0CJX0TK7Je9mpFS5zSe+mKpGnCLYEr8IkGU1l+0mQ30+phe6HUg1MuPOCtatfhYHr64NUs37uajuTmlLyBhSYlfpIgy9hf9FZDunMsAbgbeqNgo/XNZx0Zknl6X/52wgrwDh/0OR06CEr/I8brh9RftnDsEHO0v+hjn3F6vZVqA6pTQu1xlY2Y8eXk7duw/pNs7I5QSv8jxytRftJldYWbLgX8ROOs/TmXtS7p9Sm2GdG3COzOyWbFpj9/hyAlS4hc5Xpn6i3bOjXHOtQYGAU8FW5Fz7jXnXKZzLjM5OTnEYfrrtxe1oma1OH732RL+88+PRAIlfpHjnVB/0c656cAZZpZU3oGFk3rVq/DgRa2ZtW4Hny1U/7yRRIlf5Hil9hdtZi3MzLzhzkAVIOpubh/SNY30tDr84V9LyduvC72RQolfpIji+osu0tf0YGCJmS0kcAfQNS4K6ztiYoynB7Vnx75DPDdBT/RGilL73BWJRsH6i3bOvVpo+I/AHys6rnDUPqU2w3s04+0Z6/hF5xS6nF7P75CkFDrjF5FT9sCFZ9KoVjUe+eR7DuUX+B2OlEKJX0ROWfWqcTw1qD0rN+/llalr/A5HSqHELyIh0a9NAy5Pb8xfpqxi5Wbd2x/OlPhFJGSeGNCWGlXj+O3Hi8k/oiqfcKXELyIhk1ijKr8f2J5FObt4XX30hi0lfhEJqQEdG9G/XUNe+PdKNecQppT4RSSkzIw/XNGemtXieOCjhRxWlU/YUeIXkZBLqlGVp6/owJL1u9WCZxhS4heRctG/fUMGd07lpSmrmffDDr/DkUKU+EWk3Dx5eVsa1zmNez9YyJ6DassnXJQp8ZehG7q6ZjbG64putpm1LzTtPjPLMrMlZjbazKqF8gOISPiqWS2eF4dksH7nAZ74LMvvcMRTauIvYzd0jwILnXMdgRuAF71lU4C7gUznXHsglkBLhyISJbqcXo97+p3JJwvW88n8XL/DEcp2xl9qN3QEfhC+AnDOLQeamlkDb1occJqZxQEJlNCuuYhUTr/qewbdmtXjvz5dwpqte/0OJ+qVJfGXpRu6RcAvAMysG3A6kOqcWw/8H/AjsBHIc85NPNWgRSSyxMXGMHJIJ6rGxfCrUfM5ePiI3yFFtbIk/rJ0Q/csUNdrm/wuYAGQb2Z1Cfx30AxoDFQ3s2FBN1JJ+yYVkYCGtavx/DUZLN+0hyfHqr7fT2VJ/KV2Q+ec2+2cu8k5l0Ggjj8ZWAecD6xzzm11zvIfs7kAAA1vSURBVB0GPgF6BNtIZe6bVEQC+raqz519zuD9OTl8NDen9AWkXJQl8ZelG7o63jSAW4DpzrndBKp4zjKzBK+bun4EejQSkSh1/wVncnbzRP7r0yVkbcjzO5yoVGriL2M3dG2ALDNbTuDun3u8ZWcBHwPzge+97b0W8k8hIhEjLjaGP1/XiboJVbj97/PYue+Q3yFFHQvHbkIzMzPd3Llz/Q5DKikzm+ecy6zo7apc/9zCnF1c/epMujevx9vDuxIXq+dJT8WJlGvtaRHxRUZaHf4wqD1fr9rGM1+qo/aKpM7WRcQ3V3dNY+nG3bz5zTpaNajJ1V3TSl9ITpnO+EXEV49d2oZeLZJ47NPvmbV2u9/hRAUlfhHxVXxsDC9d15m0egnc/t481m3b53dIlZ4Sv4j4rnZCPG8P74oBN78zhx2606dcKfGLSFg4PbE6r9+QyfpdB7jlb3PUrEM5UuIXkbCR2bQef7omgwU5u7h79AKOFITf7eaVgRK/iISVSzo04onL2jJx6WYe/2wJ4fisUaTT7ZwiEnaG92zGlj0/8fLUNdRLqMJvLmrld0iVihK/iISl317Uip37D/GXKaupfVo8t/Zu7ndIlYYSv4iEJTPjD4M6sPtAPk+PW0b1qnFc172J32FVCkr8IhK2YmOMF67JYP+hfB779HuqxMVwZZdUv8OKeLq4KyJhrUpcDK8M60LPM5J48ONFfLZwvd8hRTwlfhEJe9XiY3n9hky6NavHfR8sVPI/RUr8IhIRTqsSy1vDux5L/p/Mz/U7pIilxC8iESOhShxvD+/G2Wck8sBHixg9+0e/Q4pISvwiElFOqxLLmzd25dwzk3nkk+9585t1focUcZT4RYIws/5mtsLMVpvZw0GmDzWzxd5rhpml+xFntKoWH8tr12dycfuGPPXFUp6fuEJP+J4AJX6RIswsFniJQP/RbYFrzaxtkdnWAec65zoCT6G+pCtclbgY/nxtJ67qksrIyat5/LMlatunjHQfv8jxugGrnXNrAczsfWAgsPToDM65GYXm/w7QzeU+iIuN4bkrO1KvehX+On0t2/Yc4k9DMqgWH+t3aGFNZ/wix0sBcgq9z/XGFeeXwJfBJpjZbWY218zmbt26NYQhylFmxiOXtOHxy9oyPmsTw96YxU61518iJX6R41mQcUHrEMysL4HE/1Cw6c6515xzmc65zOTk5BCGKEX9slcz/nJdJxbn5jH4lRlkqyevYinxixwvFyjc63cqsKHoTGbWEXgDGOicU2exYeCyjo0ZdWt3du4/xBUvf8vsdTv8DiksKfGLHG8O0NLMmplZFWAIMLbwDGbWBPgEuN45t9KHGKUYXZvWY8ydPalbvQpD3/iOD+fmlL5QlFHiFynCOZcP/BqYACwDPnTOZZnZHWZ2hzfb74BE4GUzW2hmc30KV4JomlSdMSN60r1ZIg9+vJjff55F/pECv8MKG7qrRyQI59w4YFyRca8WGr4FuKWi45Kyq50Qzzs3deXpcct4+9tslm/cw1+u60Rijap+h+Y7nfGLSKUVFxvDEwPa8X9XpTPvx50M+PM3LMzZ5XdYvlPiF5FK78ouqXwyogdmxlWvzuDdmdlR/aSvEr+IRIX2KbX54q5e9GqRxO8+y+LXoxew5+Bhv8PyhRK/iESNutWr8OaNXXmwfyvGL9nEZX/+hkVRWPWjxC8iUSUmxrizTwvev+0sDucXMPiVGbw6bQ0FUdTOT5kSfxlaKqxrZmO8lgpnm1n7QtPqmNnHZrbczJaZ2dmh/AAiIieja9N6jLvnHC5o24Bnv1zO0DdmsWHXAb/DqhClJv4ytlT4KLDQa6nwBuDFQtNeBMY751oD6QTuixYR8V2dhCq8PLQzzw3uyKLcXVz0p+mMWZBb6S/8luWM/1hLhc65Q8DRlgoLawt8BeCcWw40NbMGZlYL6A286U075JyLvgo1EQlbZsbVXdP48p5zaNWgJvd9sIg73pvH1j0/+R1auSlL4i9LS4WLgF8AmFk34HQC7Zs0B7YCb5vZAjN7w8yqB9uIWjEUET+dnlidD24/m0cvac2UFVu54IVpfLpgfaU8+y9L4i9LS4XPAnXNbCFwF7AAyCfwZHBn4BXnXCdgH3DcNQJQK4Yi4r/YGOO23mcw7u5eNEuqzr0fLOTmd+awvpLV/Zcl8ZfaUqFzbrdz7ibnXAaBOv5kAj0U5QK5zrlZ3qwfE/ghEBEJWy3q1+TjO3rwu8va8t3aHVzw/DTe/GZdpWnvpyyJvywtFdbxpkGg/ZLp3o/BJiDHzFp50/pRqBcjEZFwFRtj3NyrGRPv6023ZvV46oulDHr520rR5EOpib+MLRW2AbLMbDmBu3/uKbSKu4BRZrYYyAD+J5QfQESkPKXVS+Dt4V156brObNn9E1e8/C2PfLKYHRHcy1eZWucsQ0uFM4GWxSy7EMg8hRhFRHxlZlzasRG9z0zixUmreHtGNuO+38T9F5zJ0O5NiIuNrGdhIytaEREf1awWz39d1pYv7zmHdo1r8cTYLC5+8WumrYysOxGV+EVETtCZDWoy6pbuvDqsCz/lF3DjW7O58a3ZrNi0x+/QykSJX0TkJJgZ/ds35N/39+axS9qw4MedXPzidB78eBEb88L79k8lfhGRU1A1LpZbezdn2m/7clPPZny6YAPn/u9U/mfcsrC9AKzELyISAnWrV+Hxy9ry1QPnMqBjY17/ei29n5vC8xNXkHcgvNr9V+IXEQmhtHoJ/L+r05l4b2/OaZnEyMmrOeePk3lx0qqw+QFQ4hcRKQctG9TklWFd+NfdvejePJEXJq2k17OTeX7iCnb6XAWkxC8iUo7aNa7N6zdk8sVdvejRIpGRk1fT84+T+cMXS9mUd9CXmMr0AJeIiJya9im1+ev1mazYtIeXp67mrW/X8beZ2VzRKYXbejenRf2aFRaLzvhFRCpQq4Y1eXFIJ6b+pi9Dujbhs4UbOP/56dz8zhxmrNlWIc1AK/GLiPigSWICTw1qz4yHz+Pe81uyKGcX170+i0tGfsOHc3M4ePhIuW1biV9ExEeJNapy7/ln8u3D5/HHwR0oKHA8+PFiejw7mefGLy+XvgBUxy8iEgaqxcdyTdcmXJ2Zxsw123lnRjavTlvDq9PWcF7rBgw7qwm9WyYTExOsb6wTo8QvIhJGzIweLZLo0SKJ3J37+cesH/lwbg6Tlm0mte5pvHRdZ9LT6pzSNpT4RUTCVGrdBB7s35p7zz+TCVmb+HBuDk0Tg3ZbfkKU+EVEwlyVuBgGpDdmQHrjkKxPF3dFRKKMEr+ISJRR4hcRiTJK/CIiUUaJX0Qkyijxi4hEGSV+EZEoo8QvIhJlrCKaAD1RZrYV+CHIpCRgWwWHUxzFElwkxHK6cy65ooMpoVxDZOw3PyiW4ILFUuZyHZaJvzhmNtc5l+l3HKBYiqNYTk44xapYgqtMsaiqR0Qkyijxi4hEmUhL/K/5HUAhiiU4xXJywilWxRJcpYklour4RUTk1EXaGb+IiJwiJX4RkSgTMYnfzPqb2QozW21mD1fwttPMbIqZLTOzLDO7xxv/pJmtN7OF3uuSCoon28y+97Y51xtXz8z+bWarvL91KyCOVoU++0Iz221m91bUfjGzt8xsi5ktKTSu2P1gZo945WeFmV1UHjGdDL/Ktsp1sXFU/nLtnAv7FxALrAGaA1WARUDbCtx+I6CzN1wTWAm0BZ4EfuPD/sgGkoqMew542Bt+GPijD9/RJuD0itovQG+gM7CktP3gfV+LgKpAM688xVb0d1fMfvOlbKtcl/n7qXTlOlLO+LsBq51za51zh4D3gYEVtXHn3Ebn3HxveA+wDEipqO2X0UDgb97w34BBFbz9fsAa51xxT6aGnHNuOrCjyOji9sNA4H3n3E/OuXXAagLlym++lW2V6zKplOU6UhJ/CpBT6H0uPhVQM2sKdAJmeaN+bWaLvX/Pyv3fUI8DJprZPDO7zRvXwDm3EQIHNFC/gmI5aggwutB7P/YLFL8fwqYMFREWcalcF6tSlutISfwWZFyF34dqZjWAfwL3Oud2A68AZwAZwEbg/1VQKD2dc52Bi4FfmVnvCtpuUGZWBbgc+Mgb5dd+KUlYlKEgfI9L5Tq4ylyuIyXx5wJphd6nAhsqMgAziydwcIxyzn0C4Jzb7Jw74pwrAF6ngqoOnHMbvL9bgDHedjebWSMv1kbAloqIxXMxMN85t9mLy5f94iluP/hehorha1wq1yWqtOU6UhL/HKClmTXzfoWHAGMrauNmZsCbwDLn3POFxjcqNNsVwJKiy5ZDLNXNrObRYeBCb7tjgRu92W4EPivvWAq5lkL/DvuxXwopbj+MBYaYWVUzawa0BGZXYFzF8a1sq1yXqvKW64q8Qn6KV7ovIXDXwRrgsQredi8C/z4tBhZ6r0uAvwPfe+PHAo0qIJbmBK7iLwKyju4LIBH4Cljl/a1XQfsmAdgO1C40rkL2C4GDciNwmMCZzy9L2g/AY175WQFcXJFlqJTP4UvZVrmO3nKtJhtERKJMpFT1iIhIiCjxi4hEGSV+EZEoo8QvIhJllPhFRKKMEr+ISJRR4hcRiTL/H6kirLUN6KCiAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "input the number of test alphabet:3\n",
      "input test alphabet:abcd\n",
      "abcd->e\n",
      "input test alphabet:adec\n",
      "adec->e\n",
      "input test alphabet:edca\n",
      "edca->b\n"
     ]
    }
   ],
   "source": [
    "#用RNN实现输入连续四个字母，预测下一个字母 （One hot 编码）\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Dense, SimpleRNN\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "\n",
    "input_word = \"abcde\"\n",
    "w_to_id = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}  # 单词映射到数值id的词典\n",
    "id_to_onehot = {0: [1., 0., 0., 0., 0.], 1: [0., 1., 0., 0., 0.], 2: [0., 0., 1., 0., 0.], 3: [0., 0., 0., 1., 0.],\n",
    "                4: [0., 0., 0., 0., 1.]}  # id编码为one-hot\n",
    "\n",
    "x_train = [\n",
    "    [id_to_onehot[w_to_id['a']], id_to_onehot[w_to_id['b']], id_to_onehot[w_to_id['c']], id_to_onehot[w_to_id['d']]],\n",
    "    [id_to_onehot[w_to_id['b']], id_to_onehot[w_to_id['c']], id_to_onehot[w_to_id['d']], id_to_onehot[w_to_id['e']]],\n",
    "    [id_to_onehot[w_to_id['c']], id_to_onehot[w_to_id['d']], id_to_onehot[w_to_id['e']], id_to_onehot[w_to_id['a']]],\n",
    "    [id_to_onehot[w_to_id['d']], id_to_onehot[w_to_id['e']], id_to_onehot[w_to_id['a']], id_to_onehot[w_to_id['b']]],\n",
    "    [id_to_onehot[w_to_id['e']], id_to_onehot[w_to_id['a']], id_to_onehot[w_to_id['b']], id_to_onehot[w_to_id['c']]],\n",
    "]\n",
    "y_train = [w_to_id['e'], w_to_id['a'], w_to_id['b'], w_to_id['c'], w_to_id['d']]\n",
    "\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(x_train)\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(y_train)\n",
    "tf.random.set_seed(7)\n",
    "\n",
    "# 使x_train符合SimpleRNN输入要求：[送入样本数， 循环核时间展开步数， 每个时间步输入特征个数]。\n",
    "# 此处整个数据集送入，送入样本数为len(x_train)；输入4个字母出结果，循环核时间展开步数为4; 表示为独热码有5个输入特征，每个时间步输入特征个数为5\n",
    "x_train = np.reshape(x_train, (len(x_train), 4, 5))\n",
    "y_train = np.array(y_train)\n",
    "\n",
    "model = tf.keras.Sequential([\n",
    "    SimpleRNN(3),\n",
    "    Dense(5, activation='softmax')\n",
    "])\n",
    "\n",
    "model.compile(optimizer=tf.keras.optimizers.Adam(0.01),\n",
    "              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),\n",
    "              metrics=['sparse_categorical_accuracy'])\n",
    "\n",
    "checkpoint_save_path = \"./checkpoint/rnn_onehot_4pre1.ckpt\"\n",
    "\n",
    "if os.path.exists(checkpoint_save_path + '.index'):\n",
    "    print('-------------load the model-----------------')\n",
    "    model.load_weights(checkpoint_save_path)\n",
    "\n",
    "cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,\n",
    "                                                 save_weights_only=True,\n",
    "                                                 save_best_only=True,\n",
    "                                                 monitor='loss')  # 由于fit没有给出测试集，不计算测试集准确率，根据loss，保存最优模型\n",
    "\n",
    "history = model.fit(x_train, y_train, batch_size=32, epochs=100, callbacks=[cp_callback])\n",
    "\n",
    "model.summary()\n",
    "\n",
    "# print(model.trainable_variables)\n",
    "file = open('./weights.txt', 'w')  # 参数提取\n",
    "for v in model.trainable_variables:\n",
    "    file.write(str(v.name) + '\\n')\n",
    "    file.write(str(v.shape) + '\\n')\n",
    "    file.write(str(v.numpy()) + '\\n')\n",
    "file.close()\n",
    "\n",
    "###############################################    show   ###############################################\n",
    "\n",
    "# 显示训练集和验证集的acc和loss曲线\n",
    "acc = history.history['sparse_categorical_accuracy']\n",
    "loss = history.history['loss']\n",
    "\n",
    "plt.subplot(1, 2, 1)\n",
    "plt.plot(acc, label='Training Accuracy')\n",
    "plt.title('Training Accuracy')\n",
    "plt.legend()\n",
    "\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(loss, label='Training Loss')\n",
    "plt.title('Training Loss')\n",
    "plt.legend()\n",
    "plt.show()\n",
    "\n",
    "############### predict #############\n",
    "\n",
    "preNum = int(input(\"input the number of test alphabet:\"))\n",
    "for i in range(preNum):\n",
    "    alphabet1 = input(\"input test alphabet:\")\n",
    "    alphabet = [id_to_onehot[w_to_id[a]] for a in alphabet1]\n",
    "    # 使alphabet符合SimpleRNN输入要求：[送入样本数， 循环核时间展开步数， 每个时间步输入特征个数]。此处验证效果送入了1个样本，送入样本数为1；输入4个字母出结果，所以循环核时间展开步数为4; 表示为独热码有5个输入特征，每个时间步输入特征个数为5\n",
    "    alphabet = np.reshape(alphabet, (1, 4, 5))\n",
    "    result = model.predict([alphabet])\n",
    "    pred = tf.argmax(result, axis=1)\n",
    "    pred = int(pred)\n",
    "    tf.print(alphabet1 + '->' + input_word[pred])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
